package com.etcn.common.aop;

import java.lang.reflect.Method;
import java.lang.reflect.Type;

import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.etcn.common.json.JResult;
import com.etcn.common.redis.RedisService;

/**
 * controller返回信息封装成统一格式
s * @author: guozc
 * @date: 2014年3月27日 上午8:49:38
 */
@Aspect
@Component
public class ManageAspect {

	@Autowired
	protected RedisService redisService;
	@Autowired
	private MappingJackson2HttpMessageConverter httpConverter;

	@Pointcut(value = "@annotation(com.etcn.common.annotation.Manage)")
	public void pointCuts() {
	}

	private Method getMethod(JoinPoint joinPoint) throws SecurityException, NoSuchMethodException {
		MethodSignature joinPointObject = (MethodSignature) joinPoint.getSignature();
		return joinPointObject.getMethod();
	}

	@Around(value = "pointCuts()")
	public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
		Object object = null;
		Method m = this.getMethod(joinPoint);
		// 通过接口调用时需转成实现对象的方法
		if (m.getDeclaringClass().isInterface()) {
			m = joinPoint.getTarget().getClass().getDeclaredMethod(joinPoint.getSignature().getName(),
					m.getParameterTypes());
		}
		object = joinPoint.proceed();
		if (object == null) {
			object = buildResult(null);
		} else {
			object = buildResult(object);
		}
		Type returnType = m.getAnnotatedReturnType().getType();
		if ("void".equals(returnType.toString())) {
			HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
					.getResponse();
			HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
			httpConverter.write(object, MediaType.APPLICATION_JSON, outputMessage);
			response.getOutputStream().close();
		}
		return object;
	}

	public JResult buildResult(Object data) {
		if (data instanceof JResult) {
			return (JResult) data;
		}
		JResult jResult = new JResult();
		if (data != null) {
			jResult.setData(data);
		}
		return jResult;
	}

}
